package com.dhcc.sdc.busi.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.dhcc.cdc.sys.dao.DictionaryMapper;
import com.dhcc.cdc.sys.entity.DictionaryEntity;
import com.dhcc.core.framework.base.service.impl.BaseServiceImpl;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.DateUtil;
import com.dhcc.core.framework.util.RedisUtil;
import com.dhcc.sdc.busi.dao.SdcBusiQcMrlistMapper;
import com.dhcc.sdc.busi.dao.SdcBusiQcfitemExecResultMapper;
import com.dhcc.sdc.busi.entity.SdcBusiQcMrlistEntity;
import com.dhcc.sdc.busi.entity.SdcBusiQcitemExecResultEntity;
import com.dhcc.sdc.busi.service.ISdcBusiQcfitemExecResultService;
import com.dhcc.sds.base.cache.formitem.FormItemCache;
import com.dhcc.sds.base.cache.formitemdic.FormItemDicCache;
import com.dhcc.sds.base.dao.SdsDataConfigMapper;
import com.dhcc.sds.base.entity.SdsDataConfigEntity;
import com.dhcc.sds.base.entity.SdsQcfitemDicEntity;
import com.dhcc.sds.base.entity.SdsQcformItemEntity;
import com.dhcc.sds.standard.dao.SdsStandSourceMapper;
import com.dhcc.sds.standard.entity.SdsStandSourceEntity;
import com.dhcc.sds.standard.function.GetValueSrv;
import com.dhcc.sds.util.StrUtil;
import com.google.common.base.CharMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 质控病种项目结果值表数据服务层接口
 *
 * @author yanghangwei
 * @ClassName: SdcBusiQcfitemExecResultServiceImpl
 * @Description: TODO
 * @date 2024-02-29 14:10:15
 */
@Service("sdcBusiQcfitemExecResultService")
public class SdcBusiQcfitemExecResultServiceImpl extends BaseServiceImpl<SdcBusiQcfitemExecResultMapper, SdcBusiQcitemExecResultEntity> implements ISdcBusiQcfitemExecResultService {

    @Autowired
    private SdcBusiQcMrlistMapper sdcBusiQcMrlistMapper;
    @Autowired
    private SdsDataConfigMapper sdsDataConfigMapper;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Autowired
    private SdsStandSourceMapper sdsStandSourceMapper;
    @Autowired
    private GetValueSrv getValueSrv;
    @Autowired
    private RedisUtil redisUtil;

    // 取值用redis缓存key关键词
    private static String redisKeyWords = "GetValue_";
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public List<SdcBusiQcitemExecResultEntity> page(Page<SdcBusiQcitemExecResultEntity> page, Map<String, Object> map) {
        return this.baseMapper.page(page, map);
    }

    @Override
    public List<SdcBusiQcitemExecResultEntity> list(Map<String, Object> map) {
        return this.baseMapper.list(map);
    }

    @Override
    public void execItemResult(Long mrListId) {
        // 获取入组病种项目
        SdcBusiQcMrlistEntity inCase = sdcBusiQcMrlistMapper.selectById(mrListId);
        // 如果没有入组记录或者当前状态不是“入组”、“保存”，则不进行取值
        if (CommonUtil.isEmpty(inCase) || (!inCase.getState().equals("I") && !inCase.getState().equals("Save"))) {
            return;
        }
        Date now = new Date();
        // 病种id
        Long entityId = inCase.getEntityId();
        // 就诊号
        Long episodeId = inCase.getEpisodeId();
        // 缓存病种项目
        List<SdsQcformItemEntity> formItemList = FormItemCache.me().getFormItemList(inCase.getEntityId());
        // 遍历项目，对每个项目进行取值
        a:
        for (SdsQcformItemEntity item : formItemList) {
            // 判断项目是否执行
            SdcBusiQcitemExecResultEntity itemExec = new SdcBusiQcitemExecResultEntity();
            itemExec.setInCaseId(mrListId);
            itemExec.setFormItemId(item.getId());
            itemExec = this.baseMapper.selectOne(itemExec);
            if (itemExec != null) continue;
            String execResult = "";
            String objectId = "";
            // 获取项目数据源配置
            Wrapper<SdsDataConfigEntity> wrapper = new EntityWrapper<>();
            wrapper.eq("fitem_id", item.getId());
            int count = sdsDataConfigMapper.selectCount(wrapper);
            // 如果没有项目的数据源配置，无论是项目配置还是值域配置
            int isDefaultVal = 0;
            if (count == 0) {
                // 获取默认值
                execResult = this.expDefaultVal(item.getId());
                isDefaultVal = 1;
            }else {
                wrapper.isNull("fitem_dic_id");
                List<SdsDataConfigEntity> configs = sdsDataConfigMapper.selectList(wrapper);
                // 如果有项目数据源配置
                if (CommonUtil.isNotEmpty(configs)) {
                    for (SdsDataConfigEntity config : configs) {
                        //通过数据源配置取值
                        execResult = this.handleItemResult(episodeId, mrListId, item, config, 1);
                        if (CommonUtil.isNotEmpty(execResult)) {
                            Boolean aBoolean = redisUtil.hasKey(redisKeyWords + episodeId + "_" + item.getId());
                            if (aBoolean) {
                                objectId = redisUtil.get(redisKeyWords + episodeId + "_" + item.getId());
                                String[] s = objectId.split("_");
                                if (s.length == 2){
                                    String objectIds = s[1];
                                    Set<String> set = new HashSet<>();
                                    for (String s1 : objectIds.split(";")){
                                        set.add(s1);
                                    }
                                    objectId = s[0] + "_" + set.toString();
                                    //获取后删除
                                    redisUtil.delete(redisKeyWords + episodeId + "_" + item.getId());
                                }
                            }
                            break;
                        }
                    }
                }
                if (CommonUtil.isEmpty(execResult)) {
                    // 通过项目值域字典数据源配置信息取值
                    List<SdsQcfitemDicEntity> itemDicList = FormItemDicCache.me().getFormItemDicList(item.getId());
                    for (SdsQcfitemDicEntity itemDic : itemDicList) {
                        if (CommonUtil.equals(itemDic.getCode(), "def")) {
                            continue;
                        }
                        // 获取值域字典项数据源
                        Wrapper<SdsDataConfigEntity> dicwWpr = new EntityWrapper<>();
                        dicwWpr.eq("fitem_id", item.getId());
                        dicwWpr.eq("fitem_dic_id", itemDic.getId());
                        List<SdsDataConfigEntity> dicConfigList = sdsDataConfigMapper.selectList(dicwWpr);
                        if (CommonUtil.isEmpty(dicConfigList)) {
                            continue;
                        }
                        String dicResult = "";
                        String dicObjectId = "";
                        for (SdsDataConfigEntity config : dicConfigList) {
                            //通过数据源配置取值
                            dicResult = this.handleItemResult(episodeId, mrListId, item, config, 2);
                            if (CommonUtil.isNotEmpty(dicResult)) {
                                dicResult = itemDic.getCode();
                                Boolean aBoolean = redisUtil.hasKey(redisKeyWords + episodeId + "_" + item.getId());
                                if (aBoolean) {
                                    dicObjectId = redisUtil.get(redisKeyWords + episodeId + "_" + item.getId());
                                    String[] s = dicObjectId.split("_");
                                    if (s.length == 2) {
                                        String objectIds = s[1];
                                        Set<String> set = new HashSet<>();
                                        for (String s1 : objectIds.split(";")) {
                                            set.add(s1);
                                        }
                                        dicObjectId = s[0] + "_" + set.toString();
                                        //获取后删除
                                        redisUtil.delete(redisKeyWords + episodeId + "_" + item.getId());
                                    }
                                }
                                break;
                            }
                        }
                        if (CommonUtil.isNotEmpty(dicResult)) {
                            if (item.getBtTypeDict().getDescription().contains("多选")) {
                                execResult += "," + dicResult;
                                objectId = objectId + ";" + dicObjectId;
                            } else {
                                execResult = dicResult;
                                objectId = dicObjectId;
                                break;
                            }
                        }
                    }
                }
                if (CommonUtil.isEmpty(execResult)) {
                    // 获取默认值
                    execResult = this.expDefaultVal(item.getId());
                    isDefaultVal = 1;
                }
            }
            // 删除值中的特殊字符
            if (CommonUtil.isNotEmpty(execResult)) {
                execResult = StrUtil.clearSpecialChar(execResult);
                // 日期和数值类型项目数据处理
                if (CommonUtil.contains(item.getBtTypeDict().getCode(), "Date")) {
                    execResult = execResult.replace("年", "-");
                    execResult = execResult.replace("月", "-");
                    execResult = execResult.replace("日", "");
                }
                if (CommonUtil.equals(item.getBtTypeDict().getCode(), "DateT")) {
                    if (DateUtil.isValidDate(execResult, "yyyy-MM-dd HH:mm") || DateUtil.isValidDate(execResult)) {
                        execResult = DateUtil.formatDate(DateUtil.parse(execResult), "yyyy-MM-dd HH:mm:ss");
                    } else {
                        execResult = "";
                    }
                } else if (CommonUtil.equals(item.getBtTypeDict().getCode(), "Date")) {
                    if (DateUtil.isValidDate(execResult, "yyyy-MM-dd") || DateUtil.isValidDate(execResult, "yyyy-MM-dd HH:mm") || DateUtil.isValidDate(execResult)) {
                        execResult = DateUtil.formatDate(DateUtil.parse(execResult), "yyyy-MM-dd");
                    } else {
                        execResult = "";
                    }
                } else if (CommonUtil.equals(item.getBtTypeDict().getCode(), "Integer") || CommonUtil.equals(item.getBtTypeDict().getCode(), "Num")) {
                    execResult = extractNumericWithDecimal(execResult); // 去除非数值字符
                }
            }
            if (CommonUtil.isNotEmpty(execResult)) {
                if (1 == isDefaultVal){
                    objectId = "default_";
                }
                // 新增或更新自动取值结果
                SdcBusiQcitemExecResultEntity execEntity = new SdcBusiQcitemExecResultEntity();
                execEntity.setInCaseId(mrListId);
                execEntity.setFormItemId(item.getId());
                execEntity.setInitValue(execResult);
                execEntity.setItemResult(execResult);
                execEntity.setExecDate(now);
                execEntity.setExecTime(now);
                execEntity.setExecType("A");
                execEntity.setObjectId(objectId);
                boolean flg = this.insertOrUpdate(execEntity);
                //判断前置条件是否满足
                String triggerExp = item.getTriggerExp();
                // 根据项目前置条件，推算前置项目的值
                calcFrontItemVal(triggerExp, entityId, mrListId, objectId);
            }
        }
        // 清楚当前患者的所有缓存数据
        this.cleanRedis(episodeId);
    }


    @Override
    public String getValueByFormIdAndCaseId(Long formId, Long caseId) {
        return this.baseMapper.selectValueByFormIdAndCaseId(formId, caseId);
    }

    private String getItemCodeByTriggerExp(String triggerExp) {
        if (triggerExp.contains("contains")) {
            // 小括号及里面的内容
            String p1 = "\\(.*?\\)";
            // 查找规则公式中中括号以内的字符
            Pattern pat1 = Pattern.compile(p1);
            // 替换关联项目的值
            Matcher m1 = pat1.matcher(triggerExp);
            String itemCodeStr = "";
            while (m1.find()) {
                itemCodeStr = m1.group(0).substring(1, m1.group(0).length() - 1);
                if (!itemCodeStr.contains("\"")) {
                    break;
                }
            }
            return itemCodeStr;
        } else {
            return triggerExp.substring(triggerExp.indexOf("(") + 1, triggerExp.indexOf(")"));
        }
    }

    private String getValueByTriggerExp(String triggerExp) {
        String val = "";
        // 双引号及里面的内容
        String p1 = "\"([^\"]*)\"";
        // 查找规则公式中中括号以内的字符
        Pattern pat1 = Pattern.compile(p1);
        // 替换关联项目的值
        Matcher m1 = pat1.matcher(triggerExp);
        while (m1.find()) {
            val = m1.group(0).substring(1, m1.group(0).length() - 1);
            if (val.contains(",")) {
                val = val.split(",")[1];
                break;
            }
        }
        return val;
    }

    /**
     * 获取默认值
     *
     * @param itemId 项目id
     * @return 默认值
     */
    public String expDefaultVal(Long itemId) {
        String resultStr = "";
        // 获取项目信息
        SdsQcformItemEntity formItem = FormItemCache.me().getFormItemById(itemId);
        DictionaryEntity typeDic = dictionaryMapper.selectById(formItem.getBtType());
        String btType = typeDic.getDescription();
        List<SdsQcfitemDicEntity> itemDicList = FormItemDicCache.me().getFormItemDicList(itemId);
        if (btType.contains("多选")) {
            for (SdsQcfitemDicEntity dicEntity : itemDicList) {
                if (CommonUtil.equals(dicEntity.getIsDefault(), 1)) {
                    resultStr += dicEntity.getCode() + ",";
                }
            }
        } else {
            for (SdsQcfitemDicEntity dicEntity : itemDicList) {
                if (CommonUtil.equals(dicEntity.getIsDefault(), 1)) {
                    resultStr = dicEntity.getCode();
                    break;
                }
            }
        }
        return resultStr;
    }

    /**
     * 处理结果值
     *
     * @param episodeId
     * @param item
     * @param dataConfig
     * @param type       1：项目结果， 2：字典结果
     * @return
     */
    private String handleItemResult(Long episodeId, Long mrListId, SdsQcformItemEntity item, SdsDataConfigEntity dataConfig, Integer type) {
        String res = "";
        if (dataConfig != null) {
            Long dsId = dataConfig.getDsId();
            SdsStandSourceEntity source = sdsStandSourceMapper.selectById(dsId);
            if (!StringUtils.isEmpty(source)) {
                SdsStandSourceEntity parentSourceEntity = sdsStandSourceMapper.selectById(source.getParentId());
                String methodName = parentSourceEntity.getSourceCode();
                if (methodName.equals("LogicValue")) {
                    return getValueSrv.LogicValue(episodeId, mrListId, item.getEntityId(), dataConfig, type);
                } else {
                    try {
                        Class GetValueSrv = Class.forName("com.dhcc.sds.standard.function.GetValueSrv");
                        GetValueSrv function = (GetValueSrv) GetValueSrv.newInstance();
                        Method method = GetValueSrv.getMethod(methodName, Long.class, Long.class, Integer.class, Long.class, Long.class);
                        List<List<Map<String, Object>>> resList = (List<List<Map<String, Object>>>) method.invoke(function, episodeId, dataConfig.getDsId(), null, dataConfig.getLinkStandId(), dataConfig.getGetTiming());
                        res = calcItemVal(episodeId, item.getId(), dataConfig, resList, type, methodName);
                    } catch (Exception e) {
                        e.printStackTrace();
                        res = "";
                    }
                }
            }
        }
        return res;
    }

    /**
     * 计算结果值
     *
     * @param episodeId
     * @param itemId
     * @param dataConfig
     * @param result
     * @param type       1：项目结果， 2：字典结果
     * @return
     */
    private String calcItemVal(Long episodeId, Long itemId, SdsDataConfigEntity dataConfig, List<List<Map<String, Object>>> result, Integer type, String methodName) {
        String resultStr = "";
        // 获取项目信息
        SdsQcformItemEntity formItem = FormItemCache.me().getFormItemById(itemId);
        DictionaryEntity typeDic = dictionaryMapper.selectById(formItem.getBtType());
        String btType = typeDic.getDescription();
        // 字典类型，有值域字典
        if (CommonUtil.equals(type, 1)) { // 项目数据源取值
            // 有逻辑运算的，先执行逻辑运算
            // 有运算逻辑的项目，默认单选
            if (CommonUtil.isNotEmpty(dataConfig.getCalcExp())) {
                try {
                    String xResult = "";
                    String objectIds = "";
                    for (List<Map<String, Object>> list : result) {
                        for (Map<String, Object> map : list) {
                            SdsStandSourceEntity sdsStandSourceEntity = sdsStandSourceMapper.selectById(dataConfig.getDsId());
                            String fieldCode = sdsStandSourceEntity.getSourceCode();
                            if (CommonUtil.isEmpty(map.get(fieldCode))) {
                                continue;
                            }
                            String filedVal = StrUtil.clearSpecialChar(map.get(fieldCode).toString());
                            //add objectId
                            String objectId = "";
                            if (CommonUtil.isNotEmpty(map.get("id"))){
                                objectId = map.get("id").toString();
                            }
                            if (dataConfig.getCalcExp().contains("contains")) {
                                xResult += filedVal;
                                objectIds = objectIds + ";" + objectId;
                            } else {
                                xResult = filedVal;
                                objectIds = objectId;
                                break;
                            }
                        }
                    }
                    if (CommonUtil.isNotEmpty(xResult)) {
                        if (dataConfig.getCalcExp().contains("contains")||dataConfig.getCalcExp().contains("match")) {
                            xResult = "\"" + xResult + "\"";
                        }
                        String[] expArr = dataConfig.getCalcExp().split(",");
                        for (String subExp : expArr) {
                            String xCode = subExp.split(":")[0];
                            String xExp = subExp.split(":")[1];
                            xExp = xExp.replace("this", xResult);
                            // 运行表达式结果且返回
                            ScriptEngineManager manager = new ScriptEngineManager();
                            ScriptEngine engine = manager.getEngineByName("JavaScript");
                            if (btType.contains("字典")) {
                                if ((boolean) engine.eval(xExp)) {
                                    if (btType.contains("多选")) {
                                        resultStr += xCode + ",";
                                    } else {
                                        resultStr = xCode;
                                        //add objectId
                                        redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objectIds);
                                        return resultStr;
                                    }
                                }
                            } else {
                                resultStr = String.valueOf(engine.eval(xExp));
                                //add objectId
                                redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objectIds);
                                return resultStr;
                            }
                        }
                    }
                    redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objectIds);
                } catch (ScriptException e) {
                    throw new RuntimeException(e);
                }
                return resultStr;
            }
            if (btType.contains("字典")) { // 有字典项
                // 获取值域字典
                List<SdsQcfitemDicEntity> itemDicList = FormItemDicCache.me().getFormItemDicList(itemId);
                // 如果有值域字典，返回值域选择项
                if (itemDicList.size() > 0) {
                    Map<String, String> tmpMap = new HashMap<>();
                    for (SdsQcfitemDicEntity sdsQcfitemDicEntity : itemDicList) {
                        String itemDicCode = sdsQcfitemDicEntity.getCode();
                        if (CommonUtil.equals(itemDicCode, "def")) {
                            continue;
                        }
                        String itemDicDesc = sdsQcfitemDicEntity.getDesc();
                        // 如果值域为是否，只需要判断存在情况
                        if ((itemDicDesc.contains("是")&&itemDicCode.equals("y")) || (itemDicDesc.contains("否")&&itemDicCode.equals("n"))) {
                            resultStr = result.size() > 0 ? "y" : "n";
                            //add objectId
                            if (result.size() > 0){
                                String objectIds = "";
                                a:for (List<Map<String, Object>> list : result){
                                    b:for (Map<String, Object> map : list){
                                        String objectId = "";
                                        if (CommonUtil.isNotEmpty(map.get("id"))){
                                            //是:取任意一个
                                            objectId = map.get("id").toString();
                                            objectIds = objectId;
                                            break a;
                                        }
                                    }
                                }
                                redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objectIds);
                            }else {
                                redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" );
                            }
                            break;
                        } else {
                            boolean isMatch = checkMatching(episodeId, formItem, sdsQcfitemDicEntity, dataConfig, result, tmpMap);
                        }
                    }
                    //创建一个新的结果集map
                    Map<String, String> resultMap = new HashMap<String, String>();
                    for (String key : tmpMap.keySet()) {
                        String value = tmpMap.get(key);
                        if ("id".equals(key)){
                            redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" +  value);
                        }
                        if (!resultMap.containsValue(value) && !"id".equals(key)) {
                            resultMap.put(key, value);
                        }
                    }
                    if (btType.contains("多选")) {
                        for (String key : resultMap.keySet()) {
                            String value = resultMap.get(key);
                            if (CommonUtil.isNotEmpty(value)) {
                                resultStr += value + ",";
                            }
                        }
                        if (resultStr.endsWith(",")) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                    } else {
                        for (String key : resultMap.keySet()) {
                            String value = resultMap.get(key);
                            if (CommonUtil.isNotEmpty(value)) {
                                resultStr = resultMap.get(key);
                                break;
                            }
                        }
                    }
                }
            } else {
                // 无值域字典，且有数据源字段
                // 获取数据源输出字段值
                resultStr = this.getFieldVal(episodeId, dataConfig, result, methodName, itemId);
            }
        } else if (CommonUtil.equals(type, 2) && CommonUtil.isNotEmpty(dataConfig.getCalcExp())) {
            // 在值域中出现基础信息，必定是牵涉到结果值判断，故必须有逻辑算式
            String xResult = "";
            String objectIds = "";
            for (List<Map<String, Object>> list : result) {
                for (Map<String, Object> map : list) {
                    SdsStandSourceEntity sdsStandSourceEntity = sdsStandSourceMapper.selectById(dataConfig.getDsId());
                    String fieldCode = sdsStandSourceEntity.getSourceCode();
                    if (CommonUtil.isEmpty(map.get(fieldCode))) {
                        continue;
                    }
                    String filedVal = StrUtil.clearSpecialChar(map.get(fieldCode).toString());
                    String objectId = "";
                    if (CommonUtil.isNotEmpty(map.get("id"))){
                        objectId = map.get("id").toString();
                    }
                    if (dataConfig.getCalcExp().contains("contains")) {
                        xResult += filedVal;
                        objectIds = objectIds + ";" + objectId;
                    } else {
                        xResult = filedVal;
                        objectIds = objectId;
                        break;
                    }
                }
            }
            String xret = xCalExp(xResult, dataConfig.getCalcExp());
            if (CommonUtil.equals(xret, "true")) {
                resultStr = "true"; //仅以此代表结果满足
                redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objectIds);
            } else {
                resultStr = "";
            }
        } else {
            // 无值域字典，且有数据源字段
            // 获取数据源输出字段值
            resultStr = this.getFieldVal(episodeId, dataConfig, result, methodName, itemId);
        }

        return resultStr;
    }

    public String extractNumericWithDecimal(String input) {
//        boolean containsNonNumeric = input.matches(".*[^\\d.].*"); // 判断是否包含除小数点外的非数值字符
//
//        if (containsNonNumeric) {
//            String patten = "\\s*([\\d.]+)";
//            Pattern regex = Pattern.compile(patten);
//            Matcher matcher = regex.matcher(input);
//            if (matcher.find()) {
//                input = matcher.group(1);
//            }
//        }
        input = input.replaceAll("[^\\d.-]","");
        return input;
    }

    /**
     * 根据项目前置条件，推算前置项目的值
     * 【递归调用】
     *
     * @param triggerExp
     * @param entityId
     * @param mrListId
     */
    public void calcFrontItemVal(String triggerExp, Long entityId, Long mrListId, String objectId) {
        if (!CommonUtil.isEmpty(triggerExp) && !triggerExp.contains(">") && !triggerExp.contains("!=") && !triggerExp.contains("||")) {
            if (triggerExp.contains("HD-0-1-1") || triggerExp.contains("DPD-0-1-10") || triggerExp.contains("STEMI-3-2-3-1") || triggerExp.contains("STEMI-3-2-3-3")) {
                // 两个血透病种特殊处理，季度项目不倒推取值 心梗两个项目20231107
                return;
            }
            //目前根据前置条件反推项目值：:(CM-0-3-3)=="a"和:[(STEMI-3-2-1)=="y"]&&[(STEMI-3-2-2)=="y"]
            if (triggerExp.contains("&&")) {
                triggerExp = triggerExp.replace("[", "").replace("]", "");
                String[] split = triggerExp.split("&&");
                for (String s : split) {
                    Map<String,String> expMap = calTriggerExp(s, entityId, mrListId, objectId);
                    String expStr = expMap.get("expStr");
                    if (CommonUtil.isNotEmpty(expStr)) {
                        // 递归推算
                        String objectIdNew = expMap.get("objectId");
                        calcFrontItemVal(expStr, entityId, mrListId, objectIdNew);
                    }
                }
            } else {
                Map<String,String> expMap = calTriggerExp(triggerExp, entityId, mrListId, objectId);
                String expStr = expMap.get("expStr");
                if (CommonUtil.isNotEmpty(expStr)) {
                    // 递归推算
                    String objectIdNew = expMap.get("objectId");
                    calcFrontItemVal(expStr, entityId, mrListId, objectIdNew);
                }
            }
        }
    }

    private boolean checkMatching(Long episodeId, SdsQcformItemEntity formItem, SdsQcfitemDicEntity sdsQcfitemDicEntity, SdsDataConfigEntity dataConfig, List<List<Map<String, Object>>> result, Map<String, String> tmpMap) {
        String itemDicDesc = sdsQcfitemDicEntity.getDesc();
        String keywords = sdsQcfitemDicEntity.getKeyword();
        boolean hasKeywords = CommonUtil.isNotEmpty(keywords);
        String itemDicCode = sdsQcfitemDicEntity.getCode();

        for (List<Map<String, Object>> list : result) {
            for (Map<String, Object> map : list) {
                if (!StringUtils.isEmpty(dataConfig.getDsId())) {
                    SdsStandSourceEntity sdsStandSourceEntity = sdsStandSourceMapper.selectById(dataConfig.getDsId());
                    String fieldCode = sdsStandSourceEntity.getSourceCode();
                    if (CommonUtil.isNotEmpty(map.get(fieldCode))) {
                        String mapFieldValue = map.get(fieldCode).toString().replaceAll("\r|\n", "");
                        String objectId = "";
                        if (CommonUtil.isNotEmpty(map.get("id"))){
                            objectId = map.get("id").toString();
                        }
                        if (hasKeywords) {
                            // 解决关键词联用的问题（阿司匹林，氯吡格雷->阿司匹林＋氯吡格雷）
                            if (keywords.contains("＋") || keywords.contains("+")) {
                                keywords = keywords.replace("＋", "+");
                                boolean joinFlg = true;
                                Map<String, String> subMap = new HashMap<>();
                                for (String subKeyStr : keywords.split("\\+")) {
                                    if (CommonUtil.isEmpty(tmpMap.get(subKeyStr)) && !mapFieldValue.contains(subKeyStr)) {
                                        joinFlg = false;
                                    } else {
                                        subMap.put(subKeyStr, itemDicCode);
                                    }
                                }
                                if (joinFlg) {
                                    //缓存
                                    redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                                    tmpMap.putAll(subMap);
                                    //add objectId
                                    if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                        tmpMap.put("id",objectId);
                                    }else {
                                        String objectIds = tmpMap.get("id");
                                        objectIds = objectIds + ";" + objectId;
                                        tmpMap.put("id",objectIds);
                                    }
                                    return true;
                                }
                            } else if (mapFieldValue.matches(".*" + keywords + ".*")) {
                                //缓存
                                redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                                tmpMap.put(keywords, itemDicCode);
                                //add objectId
                                if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                    tmpMap.put("id",objectId);
                                }else {
                                    String objectIds = tmpMap.get("id");
                                    objectIds = objectIds + ";" + objectId;
                                    tmpMap.put("id",objectIds);
                                }
                                return true;
                            }
                        } else {
                            // 解决联用项字典的问题（阿司匹林，氯吡格雷->阿司匹林＋氯吡格雷）
                            if (itemDicDesc.contains("＋") || itemDicDesc.contains("+")) {
                                itemDicDesc = itemDicDesc.replace("＋", "+");
                                boolean joinFlg = true;
                                Map<String, String> subMap = new HashMap<>();
                                for (String subDicStr : itemDicDesc.split("\\+")) {
                                    if (CommonUtil.isEmpty(tmpMap.get(subDicStr)) && !mapFieldValue.contains(subDicStr)) {
                                        joinFlg = false;
                                    } else {
                                        subMap.put(subDicStr, itemDicCode);
                                    }
                                }
                                if (joinFlg) {
                                    //缓存
                                    redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                                    tmpMap.putAll(subMap);
                                    //add objectId
                                    if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                        tmpMap.put("id",objectId);
                                    }else {
                                        String objectIds = tmpMap.get("id");
                                        objectIds = objectIds + ";" + objectId;
                                        tmpMap.put("id",objectIds);
                                    }
                                    return true;
                                }
                            }

                            if (itemDicDesc.contains(mapFieldValue) ||
                                    mapFieldValue.contains(itemDicDesc)) {
                                //缓存
                                redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                                tmpMap.put(itemDicDesc, itemDicCode);
                                //add objectId
                                if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                    tmpMap.put("id",objectId);
                                }else {
                                    String objectIds = tmpMap.get("id");
                                    objectIds = objectIds + ";" + objectId;
                                    tmpMap.put("id",objectIds);
                                }
                                return true;
                            }
                        }

                        if (formItem.getBtDesc().contains("编码")) {
                            String dicDesc = GetKeysByCode(itemDicDesc);
                            boolean flg = checkICDArea(mapFieldValue, dicDesc);
                            if (flg) {
                                //缓存
                                redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                                tmpMap.put(itemDicDesc, itemDicCode);
                                //add objectId
                                if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                    tmpMap.put("id",objectId);
                                }else {
                                    String objectIds = tmpMap.get("id");
                                    objectIds = objectIds + ";" + objectId;
                                    tmpMap.put("id",objectIds);
                                }
                                return true;
                            }
                        }
                    }
                } else {
                    for (String key : map.keySet()) {
                        if (Objects.equals(itemDicDesc, map.get(key))) {
                            //缓存
                            redisUtil.set(redisKeyWords + episodeId + "_" + formItem.getBtCode(), map);
                            tmpMap.put(itemDicDesc, itemDicCode);
                            //add objectId
                            String objectId = "";
                            if (CommonUtil.isNotEmpty(map.get("id"))){
                                objectId = map.get("id").toString();
                            }
                            if (CommonUtil.isEmpty(tmpMap.get("id"))){
                                tmpMap.put("id",objectId);
                            }else {
                                String objectIds = tmpMap.get("id");
                                objectIds = objectIds + ";" + objectId;
                                tmpMap.put("id",objectIds);
                            }
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 验证ICD是否在区间内
     *
     * @return
     */
    public boolean checkICDArea(String icd, String icdArea) {
        boolean flg = false;
        if (CommonUtil.isEmpty(icd) || CommonUtil.isEmpty(icdArea)) {
            return false;
        }
        //定义operCode的字母和数字
        String a1 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')).retainFrom(icd);
        String s3 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(icd);
        Double l3 = Double.valueOf(s3);

        icdArea = icdArea.replace("，", ",");
        icdArea = icdArea.replace("、", ",");
        icdArea = icdArea.replace("——", "~");
        icdArea = icdArea.replace("-", "~");
        icdArea = icdArea.replace("至", "~");
        // 区间直接包含icd
        if (icdArea.contains(icd)) {
            flg = true;
        } else {
            // 只有一个区间
            if (icdArea.contains("~") && !icdArea.contains(",")) {
                String[] split = icdArea.split("~");
                //字母获取
                String a2 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')).retainFrom(split[0]);
                //数字获取
                String s1 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(split[0]);
                String s2 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(split[1]);
                //字母判断
                if (Objects.equals(a1, a2)) {
                    Double l1 = Double.valueOf(s1);
                    Double l2 = Double.valueOf(s2);
                    if (l1 <= l3 && l3 <= l2) {
                        flg = true;
                    } else if (s3.contains(s1) || s3.contains(s2)) {
                        flg = true;
                    }
                }
            } else if (icdArea.contains(",")) {
                // 有多个区间
                String[] split = icdArea.split(",");
                for (String s : split) {
                    if (s.contains("~")) {
                        String[] subSplit = s.split("~");
                        //字母获取
                        String a2 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')).retainFrom(subSplit[0]);
                        //数字获取
                        String s1 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(subSplit[0]);
                        String s2 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(subSplit[1]);
                        //字母判断
                        if (Objects.equals(a1, a2)) {
                            Double l1 = Double.valueOf(s1);
                            Double l2 = Double.valueOf(s2);
                            if (l1 <= l3 && l3 <= l2) {
                                flg = true;
                                break;
                            } else if (s3.contains(s1) || s3.contains(s2)) {
                                flg = true;
                                break;
                            }
                        }
                    } else {
                        //字母获取
                        String a2 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')).retainFrom(s);
                        //数字获取
                        String s1 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(s);
                        //字母判断
                        if (Objects.equals(a1, a2)) {
                            if (s3.contains(s1)) {
                                flg = true;
                                break;
                            }
                        }
                    }
                }
            } else {
                //字母获取
                String a2 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')).retainFrom(icdArea);
                //数字获取
                String s1 = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(icdArea);
                //字母判断
                if (Objects.equals(a1, a2)) {
                    if (s3.contains(s1)) {
                        flg = true;
                    }
                }
            }
        }
        return flg;
    }

    private Map<String,String> calTriggerExp(String triggerExp, Long entityId, Long mrListId, String objectId) {
        Map<String,String> res = new HashMap<>();
        String expStr = "";
        String expObjectId = "";
        Date now = new Date();
        String itemCode = this.getItemCodeByTriggerExp(triggerExp);
        String value = this.getValueByTriggerExp(triggerExp);
        SdsQcformItemEntity sdsQcformItemEntity1 = FormItemCache.me().getFormItemByCode(entityId, itemCode);
        if (CommonUtil.isNotEmpty(sdsQcformItemEntity1) && CommonUtil.isNotEmpty(value)) {
            // 判断前置项目是否执行
            SdcBusiQcitemExecResultEntity itemExecExp = new SdcBusiQcitemExecResultEntity();
            itemExecExp.setInCaseId(mrListId);
            itemExecExp.setFormItemId(sdsQcformItemEntity1.getId());
            itemExecExp = this.baseMapper.selectOne(itemExecExp);
            if (StringUtils.isEmpty(itemExecExp)) {
                // 新增或更新自动取值结果
                SdcBusiQcitemExecResultEntity execEntity = new SdcBusiQcitemExecResultEntity();
                execEntity.setInCaseId(mrListId);
                execEntity.setFormItemId(sdsQcformItemEntity1.getId());
                execEntity.setInitValue(value);
                execEntity.setItemResult(value);
                execEntity.setExecDate(now);
                execEntity.setExecTime(now);
                execEntity.setExecType("A");
                execEntity.setObjectId(objectId);
                boolean flg = this.insertOrUpdate(execEntity);

                expStr = sdsQcformItemEntity1.getTriggerExp();
                expObjectId = objectId;
            } else {
                DictionaryEntity typeDic = dictionaryMapper.selectById(sdsQcformItemEntity1.getBtType());
                String btType = typeDic.getDescription();
                if (btType.contains("多选")) {
                    String objectIdOld = itemExecExp.getObjectId();
                    if (!itemExecExp.getItemResult().contains(value)) {
                        value = itemExecExp.getItemResult() + "," + value;
                        if (CommonUtil.isNotEmpty(objectIdOld)){
                            expObjectId = objectIdOld + ";" + objectId;
                        }else {
                            expObjectId = objectId;
                        }
                        // 新增或更新自动取值结果
                        itemExecExp.setInitValue(value);
                        itemExecExp.setItemResult(value);
                        itemExecExp.setExecDate(now);
                        itemExecExp.setExecTime(now);
                        itemExecExp.setExecType("A");
                        itemExecExp.setObjectId(expObjectId);
                        boolean flg = this.updateById(itemExecExp);

                        expStr = sdsQcformItemEntity1.getTriggerExp();
                    }
                }else if (btType.contains("单选")){
                    //解决:(TIA-1-2-1-1)=="y"倒推只能TIA-1-2-1-1取值为y的情况
                    //TIA-1-2-1-1默认为否，如果TIA-1-2-1-2有值倒退修改默认值
                    String objects = itemExecExp.getObjectId();
                    if ("default_".equals(objects)){
                        itemExecExp.setItemResult(value);
                        itemExecExp.setExecDate(now);
                        itemExecExp.setExecTime(now);
                        itemExecExp.setObjectId(objectId);

                        boolean flg = this.updateById(itemExecExp);
                        expStr = sdsQcformItemEntity1.getTriggerExp();
                    }
                }
            }
        }
        res.put("expStr", expStr);
        res.put("objectId", expObjectId);
        return res;
    }

    private String getFieldVal(Long episodeId, SdsDataConfigEntity dataConfig, List<List<Map<String, Object>>> result, String methodName , Long itemId) {
        String objVal = "";
        SdsStandSourceEntity sdsStandSourceEntity = sdsStandSourceMapper.selectById(dataConfig.getDsId());
        String fieldCode = sdsStandSourceEntity.getSourceCode();
        //关联了取值项目
        if (!StringUtils.isEmpty(dataConfig.getValueItemCode())) {
            //获取缓存中的值
            Boolean aBoolean = redisUtil.hasKey(redisKeyWords + episodeId + "_" + dataConfig.getValueItemCode());
            if (aBoolean) {
                String s = redisUtil.get(redisKeyWords + episodeId + "_" + dataConfig.getValueItemCode());
                Map<String, Object> map = (Map<String, Object>) JSON.parse(s);
                objVal = map.get(fieldCode).toString();
                //获取后删除
                redisUtil.delete(redisKeyWords + episodeId + "_" + dataConfig.getValueItemCode());
            }
        } else {
            a:
            for (List<Map<String, Object>> list : result) {
                for (Map<String, Object> map : list) {
                    if (CommonUtil.isNotEmpty(map.get(fieldCode))) {
                        objVal = map.get(fieldCode).toString();
                        String objId = "";
                        if (CommonUtil.isNotEmpty(map.get("id"))){
                            objId = map.get("id").toString();
                        }
                        if (!StringUtils.isEmpty(objVal)) {
                            redisUtil.set(redisKeyWords + episodeId + "_" + itemId, methodName + "_" + objId);
                            break a;
                        }
                    }
                }
            }
        }
        return objVal;
    }

    public String xCalExp(String result, String calExp) {
        String xRet = "";
        if (CommonUtil.isEmpty(calExp)) return xRet;
        if (CommonUtil.contains(calExp, ":")) {
            calExp = calExp.split(":")[1];
        }
        calExp = calExp.replace("this", "\"" + result + "\"");
        // 运行表达式结果且返回
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        try {
            xRet = engine.eval(calExp).toString();
        } catch (ScriptException e) {
            return xRet;
        }
        return xRet;
    }

    private String GetKeysByCode(String dicDesc) {
        if (dicDesc.contains(":") || dicDesc.contains("：")) {
            // 区间范围
            dicDesc = dicDesc.replace("：", ":").replace(" ", "");
            dicDesc = dicDesc.split(":")[1];
            dicDesc = dicDesc.replace("至", "-");
        } else {
            String icdCode = "";
            int l = dicDesc.length();
            for (int i = 0; i < l; i++) {
                char xcon = dicDesc.charAt(i);
                if ("".equals(xcon) || xcon > 127) {
                    break;
                }
                icdCode = icdCode + xcon;
            }
            dicDesc = icdCode;
        }
        return dicDesc;
    }

    /**
     * 清除当前取值redis缓存数据
     */
    public void cleanRedis(Long episodeId) {
        redisUtil.deleteByKeyWords(redisKeyWords + episodeId + "_");
    }
}